/**
 *		Licensed to the Apache Software Foundation (ASF) under one
 *     or more contributor license agreements.  See the NOTICE file
 *     distributed with this work for additional information
 *     regarding copyright ownership.  The ASF licenses this file
 *     to you under the Apache License, Version 2.0 (the
 *     "License"); you may not use this file except in compliance
 *     with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *      Unless required by applicable law or agreed to in writing,
 *     software distributed under the License is distributed on an
 *     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *     KIND, either express or implied.  See the License for the
 *     specific language governing permissions and limitations
 *     under the License.
 *     
 *     Image Resizer Project
 */

package image.resizer.ui;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Locale;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import image.resizer.ResizerConfig;
import image.resizer.Utils;

/**
 * Resize Engine configuration object wrapper,
 * extended for UI purposes.
 * 
 * @author Dudarev Ilya
 */
public class ResizerUIConfig {

	private static final String CLASS_NAME = ResizerUIConfig.class.getName();
	private static final Logger logger = Logger.getLogger(ResizerUIConfig.class.getPackage().getName());
	private static final Level FINER_LEVEL = Level.FINER;
	
	private static final String UI_CONFIG_PATH = "uiconfig.properties";
	private static final String RESIZE_ENGINE_LOG_LEVEL_KEY = "resize.engine.log.level";
	private static final String LOCALE_KEY = "resize.engine.ui.locale";
	private ResizerConfig innerConfig;
	private ResizerConfig tempConfig;
	private Level engineLogLevel = Level.WARNING;
	private Locale uiLocale = Locale.getDefault();

	public ResizerUIConfig() {
		if(logger.isLoggable(FINER_LEVEL))
		{
			logger.entering(CLASS_NAME, "constructor");
		}
		innerConfig = new ResizerConfig();
		loadFromFile();
		tempConfig = innerConfig;
		if(logger.isLoggable(FINER_LEVEL))
		{
			logger.exiting(CLASS_NAME, "constructor");
		}
	}
	
	public void loadFromFile()
	{
		if(logger.isLoggable(FINER_LEVEL))
		{
			logger.entering(CLASS_NAME, "loadFromFile");
		}
		File configFile = new File(UI_CONFIG_PATH);
		innerConfig = new ResizerConfig();
		Properties props = null;
		if(configFile.exists())
		{
			try
			{
				FileInputStream fis = new FileInputStream(configFile);
				props = new Properties();
				props.load(fis);
				innerConfig.loadFromProperties(props);
			}
			catch (IOException e) {
				logger.logp(Level.WARNING, CLASS_NAME, "loadFromFile",
						"Failed to load configuration from file.", e);
			}
		}
		if(props != null)
		{
			String logLevel = props.getProperty(RESIZE_ENGINE_LOG_LEVEL_KEY);
			if(!Utils.isEmpty(logLevel))
			{
				try
				{
					engineLogLevel = Level.parse(logLevel);
				}
				catch (Exception e) {
					//nothing to do
				}
			}
			String localeString = props.getProperty(LOCALE_KEY);
			if(!Utils.isEmpty(localeString))
			{
				try
				{
					uiLocale = new Locale(localeString);
				}
				catch (Exception e) {
					// nothing to do
				}
			}
		}
		if(logger.isLoggable(FINER_LEVEL))
		{
			logger.exiting(CLASS_NAME, "loadFromFile");
		}
	}
	
	public void saveToFile()
	{
		if(logger.isLoggable(FINER_LEVEL))
		{
			logger.entering(CLASS_NAME, "saveToFile");
		}
		File configFile = new File(UI_CONFIG_PATH);
		if(configFile.exists() && configFile.isDirectory())
		{
			RuntimeException rte = new RuntimeException("Failed to save configuration file to "+UI_CONFIG_PATH+" - is detected as directory. ");
			logger.throwing(CLASS_NAME, "saveToFile", rte);
			throw rte;
		}
		Properties props = new Properties();
		innerConfig.storeToProperties(props);
		// UI properties
		props.setProperty(RESIZE_ENGINE_LOG_LEVEL_KEY, engineLogLevel.toString());
		props.setProperty(LOCALE_KEY, uiLocale.getLanguage()); //TODO check code ?
		try
		{
			FileOutputStream fos = new FileOutputStream(configFile);
			props.store(fos, "Image resizer UI configuration.");
		}
		catch (IOException e) {
			RuntimeException rte = new RuntimeException(e);//TODO chacked exception?
			logger.throwing(CLASS_NAME, "saveToFile", rte);
			throw rte;
		}
		if(logger.isLoggable(FINER_LEVEL))
		{
			logger.exiting(CLASS_NAME, "saveToFile");
		}
	}
	
	public void clearChanges()
	{
		tempConfig = (ResizerConfig)innerConfig.clone();
	}
	
	public void storeChanges()
	{
		innerConfig = (ResizerConfig)tempConfig.clone();
	}

	public ResizerConfig getInnerConfig()
	{
		return (ResizerConfig)innerConfig.clone();
	}
	
	public String getSourceDirPath()
	{
		return innerConfig.getSourceDirPath();
	}
	
	public void setSourceDirPath(String sourcePath)
	{
		tempConfig.setSourceDirPath(sourcePath);
	}
	
	public String getTargetDirPath()
	{
		return innerConfig.getTargetDirPath();
	}
	
	public void setTargetDirPath(String targetPath)
	{
		tempConfig.setTargetDirPath(targetPath);
	}
	
	public int getMaxImageSize()
	{
		return innerConfig.getMaxImageSize();
	}
	
	public void setMaxImageSize(int maxSize)
	{
		tempConfig.setMaxImageSize(maxSize);
	}
	
	public int getNumOfThreads()
	{
		return innerConfig.getNumOfThreads();
	}
	
	public void setNumOfThreads(int numOfThreads)
	{
		tempConfig.setNumOfThreads(numOfThreads);
	}
	
	public boolean isSearchSubDirs()
	{
		return tempConfig.isSearchSubDirs();
	}
	
	public void setSearchSubDirs(boolean searchSubDirs)
	{
		tempConfig.setSearchSubDirs(searchSubDirs);
	}
	
	public Level getEngineLoggingLevel()
	{
		return engineLogLevel;
	}
	
	public void setEngineLogLevel(Level level)
	{
		engineLogLevel = level;
	}
	
	public Locale getUILocale()
	{
		return uiLocale;
	}
	
	public void setUILocale(Locale locale)
	{
		uiLocale = locale;
	}
}
